﻿using Microsoft.EntityFrameworkCore;
using MyBlog2.Models;
using MyBlog2.ViewModels;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace MyBlog2.Repository
{
    public class ArticleRepository : IArticleRepository
    {
        private readonly AppDbContext _context;

        public ArticleRepository(AppDbContext context)
        {
            this._context = context;
        }


        /// <summary>
        /// 添加一个文章
        /// </summary>
        /// <param name="articleClassify"></param>
        /// <returns></returns>
        public Article AddArticle(Article article)
        {
            //判断输入添加的文章的类别是否在
            var classify = _context.ArticleClassifys.FirstOrDefault(c=>c.Id == article.ArticleClassifyId);
            if (classify == null)
            {
                return null;
            }
            _context.Articles.Add(article);
            _context.SaveChanges();
            return article;
        }


        /// <summary>
        /// 删除一个文章
        /// </summary>
        /// <param name="id"></param>
        public bool DeleteArticle(int id)
        {
            var article = _context.Articles.FirstOrDefault(a => a.Id == id);
            if (article == null)
            {
                return false;
            }
            _context.Articles.Remove(article);
            return _context.SaveChanges() > 0;
        }

        /// <summary>
        /// 编辑一个文章
        /// </summary>
        /// <param name="articleClassify"></param>
        /// <returns></returns>
        public Article EditArticle(Article article)
        {
            var art = _context.Articles.Include(a=>a.ArticleTag).ThenInclude(at=>at.Tag).FirstOrDefault(a => a.Id == article.Id);
            if (art != null)
            {
                art.ArticleClassifyId = article.ArticleClassifyId;
                art.Title = article.Title;
                art.Flag = article.Flag;
                art.Description = article.Description;
                art.Contents = article.Contents;
                art.ShareStatement = article.ShareStatement;
                art.CommentAbled = article.CommentAbled;
                art.Published = article.Published;
                art.TagIds = article.TagIds;
                art.UpdateTime = DateTime.Now;


                art.ArticleTag = article.ArticleTag;
                _context.Articles.Update(art);
                _context.SaveChanges();
                return art;
            }
            else
            {
                return null;
            }
        }


        /// <summary>
        /// 获取文章总数
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public int GetArticleCount(Expression<Func<Article, bool>> where)
        {
            return _context.Articles.Where(where).Count();
        }


        /// <summary>
        /// 分页获取文章列表
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="total"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public List<Article> GetArticleList(int pageIndex, int pageSize, out int totalPageCount)
        {
            var query = _context.Articles.Include("ArticleClassify").Include("ArticleComment").AsQueryable();
            //foreach (var item in where)
            //{
            //    query = query.Where(item);
            //}
            var count = query.Count();  //查询到的总条数
            totalPageCount = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;   //总页数
            var pageData = query.OrderByDescending(a=>a.CreateTime).Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();
            return pageData;
        }


        /// <summary>
        /// 获取文章前x条
        /// </summary>
        /// <param name="where"></param>
        /// <param name="topCount"></param>
        /// <returns></returns>
        public List<Article> GetArticleListTop(Expression<Func<Article, bool>> where, int topCount)
        {
            //获取符合条件的前topcount条新闻
            var list = _context.Articles.Include("ArticleClassify").Include("ArticleComment").Where(where).OrderByDescending(c => c.CreateTime).Take(topCount);
            return list.ToList();
        }


        /// <summary>
        /// 根据分类id获取文章列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<Article> GetArticleListByClassifyId(int id)
        {
            if (id < 0)
            {
                return _context.Articles.OrderByDescending(a => a.UpdateTime).ToList();
            }
            else
            {
                var c = _context.ArticleClassifys.Find(id);
                if (c != null)  //分类存在
                {
                    return _context.Articles.Where(a => a.ArticleClassifyId == id).OrderByDescending(a=>a.UpdateTime).ToList();
                }
                else
                {
                    return null;
                }
            }
            
            
        }


        /// <summary>
        /// 根据标签id获取文章列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<Article> GetArticleListByTagId(int id)
        {
            if (id < 0)
            {
                return _context.Articles.OrderByDescending(a => a.UpdateTime).ToList();
            }
            else
            {
                var t = _context.Tags.Find(id);
                if (t != null)  //标签存在
                {
                    var a = _context.Articles.Include(a => a.ArticleTag).ToList();
                    List<Article> arts = new List<Article>();
                    foreach (var item in a)
                    {
                        foreach (var item2 in item.ArticleTag)
                        {
                            if (item2.TagId == id)
                            {
                                arts.Add(item2.Article);
                            }
                        }
                    }
                    return arts;
                }
                else
                {
                    return null;
                }
            }
        }


        /// <summary>
        /// 获取一个文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Article GetOneArticle(int id)
        {
            return _context.Articles.FirstOrDefault(a=>a.Id == id);
        }

        /// <summary>
        /// 最新文章
        /// </summary>
        /// <param name="top"></param>
        /// <returns></returns>
        public List<Article> GetRecentArticles(int top)
        {
            return _context.Articles.AsNoTracking().OrderByDescending(a=>a.UpdateTime).Take(top).ToList();
        }


        /// <summary>
        /// 搜索文章
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public List<Article> SearchArticles(Expression<Func<Article, bool>> where)
        {
            return _context.Articles.Include("ArticleClassify").Where(where).OrderByDescending(a => a.CreateTime).ToList();
        }


        //归档查询
        public Dictionary<int,IEnumerable<Article>> ArticleArchive(List<int> years)
        {
            var dic = new Dictionary<int, IEnumerable<Article>>();
            foreach (var year in years)
            {
                var arts = _context.Articles.AsNoTracking().Where(a=>a.CreateTime.Year==year).OrderByDescending(a => a.CreateTime).ToList();
                dic.Add(year,arts);
            }
            return dic;
        }

        /// <summary>
        /// 所有文章年份
        /// </summary>
        /// <returns></returns>
        public List<int> GetYears()
        {
            var years = _context.Articles.GroupBy(a => a.CreateTime.Year, (key, value) => key).ToList();
            years.Reverse();
            return years;
        }


        /// <summary>
        /// 更新浏览次数
        /// </summary>
        public void UpdateViews(Article article)
        {
            _context.Articles.Attach(article);
            article.Views += 1;
            _context.SaveChanges();
        }



        ///// <summary>
        ///// 搜索文章（全匹配）
        ///// </summary>
        ///// <param name="where"></param>
        ///// <returns></returns>
        //public List<Article> SearchArticles(List<Expression<Func<Article, bool>>> where)
        //{
        //    var list = _context.Articles.Include("ArticleClassify");
        //    foreach (var item in where)
        //    {
        //        list = list.Where(item);
        //    }
        //    var data = list.OrderByDescending(a => a.CreateTime).ToList();
        //    return data;
        //}



    }
}
